#include "Renderer.h"

#include <cstdio>
#include <map>
#include <string>

#include <opencv/cv.h>
#include <opencv/highgui.h>

using namespace std;

Renderer::Renderer(int width, int height, int alpha, int beta) {
    this->width = width;
    this->height = height;
    this->alpha = alpha;
    this->beta = beta;
}

//void Renderer::draw_bound(Node* raiz, map<Node*, int> *id, CvFont* font, IplImage* image, int posX, int posY) {
void Renderer::draw_bound(Node* raiz, CvFont* font, IplImage* image, int posX, int posY) {
    if(raiz->get_type() == BISS) {
        if(raiz->get_orientation() == HORIZONTAL) {
            draw_bound(raiz->get_left(), font, image, posX, posY);
            draw_bound(raiz->get_right(), font, image, posX, posY + raiz->get_left()->get_height(alpha, beta) + alpha);
        } else {
            draw_bound(raiz->get_left(), font, image, posX, posY);
            draw_bound(raiz->get_right(), font, image, posX + raiz->get_left()->get_width(alpha, beta) + alpha, posY);
        }
    } else {
        //if(raiz->get_image()->get_image()) {
            int r_width, r_height;
            r_width = raiz->get_image()->get_width(); // - 2*beta;
            r_height = raiz->get_image()->get_height(); // - 2*beta;
            IplImage* node_image = raiz->get_image()->get_image();
            IplImage* resized = cvCreateImage(cvSize(r_width, r_height), node_image->depth, node_image->nChannels);
            cvResize(node_image, resized);
            cvSetImageROI(image, cvRect(posX + beta, posY + beta, r_width, r_height));
            cvCopyImage(resized, image);
            cvResetImageROI(image);
/*        } else {
            cvRectangle(image, cvPoint(posX+beta, posY+beta), cvPoint(posX + raiz->get_image()->get_width() - beta, posY + raiz->get_image()->get_height() - beta), cvScalar(255,0,0));
            cvSet(image,cvScalar(0,0,255));
        }*/

        string sid;
        stringstream sstream;
//        sstream << id->at(raiz) << " [" << raiz->get_image()->get_relative_area() << "]";
        sstream << raiz->get_image()->get_relative_area();
        sid = sstream.str();
        cvPutText(image, sid.c_str(), cvPoint(posX + raiz->get_image()->get_width()/2.0, posY + raiz->get_image()->get_height()/2.0), font, cvScalar(255, 0, 0));
    }
}

//IplImage* Renderer::draw_tree(Node* raiz, map<Node*, int> *id) {
IplImage* Renderer::draw_tree(Node* raiz) {
//    IplImage* image = cvCreateImage(cvSize(width + 1, height + 1), IPL_DEPTH_8U, 3);
    IplImage* image = cvCreateImage(cvSize(width + width / 2.0, height + height / 2.0), IPL_DEPTH_8U, 3);
    cvSet(image, cvScalar(255,255,255));
    CvFont font;
    cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 1.0f, 1.0f);
    cvRectangle(image, cvPoint(0, 0), cvPoint(width, height), cvScalar(0,150,0));
    cvRectangle(image, cvPoint(0, 0), cvPoint(raiz->get_width(alpha, beta), raiz->get_height(alpha, beta)), cvScalar(0,0,150));
//    drawBound(raiz, id, &font, image, abso((raiz->get_width(alpha, beta) - width)/2.0), abso((raiz->get_height(alpha, beta) - height)/2.0));
    draw_bound(raiz, &font, image, 1.0, 1.0);
    return image;
}
void Renderer::text_draw_bound(Node* raiz, CvFont* font, IplImage* image, int posX, int posY) {
    if(raiz->get_type() == BISS) {
        if(raiz->get_orientation() == HORIZONTAL) {
            text_draw_bound(raiz->get_left(), font, image, posX, posY);
            text_draw_bound(raiz->get_right(), font, image, posX, posY + raiz->get_left()->get_height(alpha, beta) + alpha);
        } else {
            text_draw_bound(raiz->get_left(), font, image, posX, posY);
            text_draw_bound(raiz->get_right(), font, image, posX + raiz->get_left()->get_width(alpha, beta) + alpha, posY);
        }
    } else {

            int r_width, r_height;
            r_width = raiz->get_image()->get_width(); // - 2*beta;
            r_height = raiz->get_image()->get_height(); // - 2*beta;

            IplImage* node_image = raiz->get_image()->get_image();
            IplImage* resized = cvCreateImage(cvSize(r_width, r_height), node_image->depth, node_image->nChannels);
            cvResize(node_image, resized);
            cvSetImageROI(image, cvRect(posX + beta, posY + beta, r_width, r_height));
            
            cout << endl << raiz->get_image()->get_filename() << " " << posX + beta << " " << posY + beta << " " <<  r_width << " " << r_height;
            
            cvCopyImage(resized, image);
            cvResetImageROI(image);

//        string sid;
//        stringstream sstream;
//        sstream << raiz->get_image()->get_relative_area();
//        sid = sstream.str();
//        cvPutText(image, sid.c_str(), cvPoint(posX + raiz->get_image()->get_width()/2.0, posY + raiz->get_image()->get_height()/2.0), font, cvScalar(255, 0, 0));
    }
}
IplImage* Renderer::text_draw_tree(Node* raiz) {

    IplImage* image = cvCreateImage(cvSize(width + width / 2.0, height + height / 2.0), IPL_DEPTH_8U, 3);
    cvSet(image, cvScalar(255,255,255));
    CvFont font;
    cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 1.0f, 1.0f);
    cvRectangle(image, cvPoint(0, 0), cvPoint(width, height), cvScalar(0,150,0));
    cvRectangle(image, cvPoint(0, 0), cvPoint(raiz->get_width(alpha, beta), raiz->get_height(alpha, beta)), cvScalar(0,0,150));

    text_draw_bound(raiz, &font, image, 1.0, 1.0);
    return image;
}
